// #include "util.hpp"
// #include "level.hpp"
// #include "message.hpp"
// #include "format.hpp"
// #include "sink.hpp"
// #include "logger.hpp"
// #include "buffer.hpp"
#include "../logs/log.hpp"
#include <unistd.h>
// int main()
// {
//     std::cout << mylog::util::Date::getTime() << std::endl;
//     std::string filename = "./abc/def/test.txt";
//     std::string pathname = mylog::util::File::path(filename);
//     mylog::util::File::createDirectory(pathname);
//     return 0;
// }

// int main()
// {
//     std::cout << mylog::LogLevel::toString(mylog::LogLevel::value::DEBUG) << std::endl;
//     std::cout << mylog::LogLevel::toString(mylog::LogLevel::value::INFO) << std::endl;
//     std::cout << mylog::LogLevel::toString(mylog::LogLevel::value::WARN) << std::endl;
//     std::cout << mylog::LogLevel::toString(mylog::LogLevel::value::ERROR) << std::endl;
//     std::cout << mylog::LogLevel::toString(mylog::LogLevel::value::FATAL) << std::endl;
//     std::cout << mylog::LogLevel::toString(mylog::LogLevel::value::OFF) << std::endl;
//     std::cout << mylog::LogLevel::toString(mylog::LogLevel::value::UNKNOW) << std::endl;
//     return 0;
// }




/*扩展一个以时间作为日志文件滚动切换类型的日志落地模块
    1.以时间进行文件滚动，实际上是以时间段进行滚动
        实现思想:以当前系统时间，取模时间段大小，可以得到当前时间段是第几个时间段
        每次以当前系统时间取模，判断与当前文件的时间段是否一致，不一致代表不是同一个时间段
*/
enum class  TimeGap
{
    GAP_SECOND,
    GAP_MINUTE,
    GAP_HOUR,
    GAP_DAY
};
class RollByTimeSink : public mylog::LogSink
{
private:
    std::string _basename;
    std::ofstream _ofs;
    size_t _cur_gap;
    size_t  _gap_size;
    size_t _name_count;
private:
    std::string createNewFile()
    {
        std::stringstream ss;
        ss << _basename;
        time_t ctime = mylog::util::Date::getTime();
        struct tm lt;
        localtime_r(&ctime, &lt);
        
        ss << lt.tm_year + 1900;
        ss << lt.tm_mon + 1;
        ss << lt.tm_mday;
        ss << lt.tm_hour;
        ss << lt.tm_min;
        ss << lt.tm_sec;
        //ss << "-";
        //ss << _name_count++;
        ss << ".log";
        return  ss.str();
    }
public:
    RollByTimeSink(const std::string& basename, TimeGap gap_type):_basename(basename)
    {
        switch(gap_type)
        {
            case TimeGap::GAP_SECOND : _gap_size = 1; break;
            case TimeGap::GAP_MINUTE : _gap_size = 60; break;
            case TimeGap::GAP_HOUR : _gap_size = 3600; break;
            case TimeGap::GAP_DAY : _gap_size = 3600*24; break;
        }
        _cur_gap = _gap_size == 1 ? mylog::util::Date::getTime() : mylog::util::Date::getTime() % _gap_size;
        _name_count = 0;
        std::string pathname = createNewFile();
        // 1.创建日志所在的目录
        mylog::util::File::createDirectory(mylog::util::File::path(pathname));
        // 2.创建并打开日志文件
        _ofs.open(pathname, std::ios::binary | std::ios::app);
        assert(_ofs.is_open());
    }
    void log(const char *data, size_t len) override
    {
        time_t cur = mylog::util::Date::getTime();
       if((cur % _gap_size) != _cur_gap)
       {
            _ofs.close();
            std::string pathname = createNewFile();
            _ofs.open(pathname, std::ios::binary | std::ios::app);
            assert(_ofs.is_open());
       }
       _ofs.write(data, len);
       assert(_ofs.good());
    }
};
// int main()
// {
//     //mylog::LogMsg msg(mylog::LogLevel::value::INFO, "main.cc", 54, "格式化功能测试", "root");
//     //mylog::Formater formater("abcde[%d{%H:%M:%S}][%p]%T%m%n");
//     //std::string str = formater.format(msg);
//     // mylog::LogSink::ptr stdout_ptr = mylog::SinkFactory::create<mylog::StdoutSink>();
//     // mylog::LogSink::ptr file_ptr = mylog::SinkFactory::create<mylog::FileSink>("./logfile/test.log");
//     // mylog::LogSink::ptr rollbysize_ptr = mylog::SinkFactory::create<mylog::RollBySizeSink>("./logfile/rool-", 1024);
//     // std::vector<mylog::LogSink::ptr> sinks = {stdout_ptr, file_ptr, rollbysize_ptr};
    
//     // std::string logger_name = "sync_logger";
//     // mylog::Formater::ptr formater(new mylog::Formater("[%d{%H:%M:%S}][%t][%c][%f:%l][%p]%T%m%n"));
//     // mylog::LogLevel::value level = mylog::LogLevel::value::WARN;
//     // mylog::Logger::ptr logger(new mylog::SyncLogger(logger_name, formater, sinks, level));

//     std::unique_ptr<mylog::LoggerBuilder> loggerbuild(new mylog::LocalLoggerBuilder());
//     loggerbuild->buildLoggerName("sync_logger");
//     loggerbuild->buildLimitLevel(mylog::LogLevel::value::WARN);
//     loggerbuild->buildLoggerType(mylog::LoggerType::LOGGER_SYNC);
//     loggerbuild->buildformater("[%d{%H:%M:%S}][%p]%T%m%n");
//     loggerbuild->buildSinks<mylog::StdoutSink>();
//     loggerbuild->buildSinks<mylog::FileSink>("./logfile/test.log");
//     mylog::Logger::ptr logger = loggerbuild->build();
//     size_t count = 0;
//     size_t cursize = 0;
//     std::string str = "日志测试";
//     logger->debug(__FILE__, __LINE__, "%s", str.c_str());
//     logger->info(__FILE__, __LINE__, "%s", str.c_str());
//     logger->warn(__FILE__, __LINE__, "%s", str.c_str());
//     logger->error(__FILE__, __LINE__, "%s", str.c_str());
//     logger->fatal(__FILE__, __LINE__, "%s", str.c_str());
//     while(cursize < 1024*1024)
//     {
//         std::string tmp = str + std::to_string(count++);
//         logger->fatal(__FILE__, __LINE__, "%s", tmp.c_str());
//         cursize += tmp.size();
//     }
//     // stdout_ptr->log(str.c_str(), str.size());
//     // file_ptr->log(str.c_str(), str.size());

//     // size_t count = 0;
//     // size_t cursize = 0;
//     // while(cursize < 1024*1024*10)
//     // {
//     //     std::string tmp = str + std::to_string(count++);
//     //     rollbysize_ptr->log(tmp.c_str(), tmp.size());
//     //     cursize += tmp.size();
//     // }
//     // mylog::LogSink::ptr roolbytime_ptr = mylog::SinkFactory::create<RollByTimeSink>("./logfile/rool-", TimeGap::GAP_SECOND);
//     // time_t old = mylog::util::Date::getTime();
//     // while(mylog::util::Date::getTime() < old + 5)
//     // {
//     //     roolbytime_ptr->log(str.c_str(), str.size());
//     //     usleep(1000);
//     // }
   
//     return 0;
// }

// int main()
// {
//     //1.读取指定文件的所有数据
//     std::ifstream ifs;
//     ifs.open("./logfile/test.log", std::ios::binary);
//     if(ifs.is_open() == false)
//     {
//         std::cout << "ifs open fail" << std::endl;
//         return -1;
//     }
//     std::string body;
//     ifs.seekg(0, std::ios::end);
//     size_t  fsize = ifs.tellg();
//     ifs.seekg(0, std::ios::beg);
//     body.resize(fsize);
//     ifs.read(&body[0], fsize);
//     if(ifs.good() == false)  
//     {
//         std::cout << "read fail" << std::endl;
//         return -1;
//     }

//     //2.将数据放到缓冲区,然后从缓冲区里拿出所有数据,然后再和原来的数据进行比对
//     mylog::Buffer buffer;
//     for(int i = 0; i < body.size(); i++)
//     {
//         buffer.push(&body[i], 1);
//     }
//     std::ofstream ofs;
//     ofs.open("./logfile/tmp.log", std::ios::binary);
//     if(ofs.is_open() == false)
//     {
//         std::cout << "ofs open fail" << std::endl;
//         return -1;
//     }
//     size_t rsize = buffer.readAbleSize();
//     for(int i = 0; i < rsize; i++)
//     {
//         ofs.write(buffer.begin(), 1);
//         buffer.moveReader(1);
//     }
//     if(ofs.good() == false)
//     {
//         std::cout << "write fail" << std::endl;
//         return -1;
//     }
//     return 0;
// }

void test_log()
{
    // mylog::Logger::ptr logger = mylog::LoggerManager::GetInstance().getLogger("async_logger");
    // std::string str = "日志测试";
    // logger->debug(__FILE__, __LINE__, "%s", str.c_str());
    // logger->info(__FILE__, __LINE__, "%s", str.c_str());
    // logger->warn(__FILE__, __LINE__, "%s", str.c_str());
    // logger->error(__FILE__, __LINE__, "%s", str.c_str());
    // logger->fatal(__FILE__, __LINE__, "%s", str.c_str());
    // size_t count = 0;
    // while(count < 200000)
    // {
    //     std::string tmp = str + std::to_string(count++);
    //     logger->fatal(__FILE__, __LINE__, "%s", tmp.c_str());
    // }

    //mylog::Logger::ptr logger = mylog::LoggerManager::GetInstance().getLogger("async_logger");
    // mylog::Logger::ptr logger = mylog::LoggerManager::GetInstance().rootLogger();

    // std::string str = "日志测试";
    // logger->debug("%s", str.c_str());
    // logger->info( "%s", str.c_str());
    // logger->warn("%s", str.c_str());
    // logger->error("%s", str.c_str());
    // logger->fatal("%s", str.c_str());
    // size_t count = 0;
    // while(count < 50000)
    // {
    //     std::string tmp = str + std::to_string(count++);
    //     logger->fatal("%s", tmp.c_str());
    // }

    mylog::LoggerManager::GetInstance();
    std::string str = "日志测试";
    DEBUG("%s", str.c_str());
    INFO("%s", str.c_str());
    WARN("%s", str.c_str());
    ERROR("%s", str.c_str());
    FATAL("%s", str.c_str());
    size_t count = 0;
    while(count < 50000)
    {
        std::string tmp = str + std::to_string(count++);
        FATAL("%s", tmp.c_str());
    }
}
int main()
{
    std::unique_ptr<mylog::LoggerBuilder> loggerbuild(new mylog::GlobalLoggerBuilder());
    loggerbuild->buildLoggerName("async_logger");
    loggerbuild->buildLimitLevel(mylog::LogLevel::value::WARN);
    loggerbuild->buildLoggerType(mylog::LoggerType::LOGGER_ASYNC);
    loggerbuild->buildformater("[%d{%H:%M:%S}][%p]%T%m%n");
    loggerbuild->buildSinks<mylog::StdoutSink>();
    loggerbuild->buildSinks<mylog::FileSink>("./logfile/async.log");
    loggerbuild->buildEnableUnSafeAsync();
    loggerbuild->build();
    test_log();
    return 0;
}